function [points, path] = binn(map_size, obstacles)
points = reshape(repelem(point(0,0,0,0,0), map_size * map_size),[map_size, map_size]);
for i = 0:map_size-1
    for j = 0:map_size-1
        points(i+1,j+1).position = [i,j];
        if is_obstacle(points(i+1,j+1).position, obstacles)
            points(i+1,j+1).covered = 1;
        end
    end
end
around_points = point.empty;
path = point.empty;
current_index = [1,1];
points(1,1).covered = 1;
count = 0;
around_covered = 0;
path(end+1) = points(current_index(1,1),current_index(1,2));
% uncovered common point x1:100
% covered common point x1:0
% obstacles x1:-100
% calcaulate x1
% | 1 | 2 | 3 |
% | 4 | # | 5 |
% | 6 | 7 | 8 |
while true
    % 1
    grid1 = current_index + [-1, 1];
    if in_map(grid1, map_size)
        around_points(end+1) = points(current_index(1,1) - 1,current_index(1,2) + 1);
    end
    % 2
    grid2 = current_index + [0, 1];
    if in_map(grid2, map_size)
        around_points(end+1) = points(current_index(1,1),current_index(1,2) + 1);
    end
    % 3
    grid3 = current_index + [1, 1];
    if in_map(grid3, map_size)
        around_points(end+1) = points(current_index(1,1) + 1,current_index(1,2) + 1);
    end
    % 4
    grid4 = current_index + [-1, 0];
    if in_map(grid4, map_size)
        around_points(end+1) = points(current_index(1,1) - 1,current_index(1,2));
    end
    % 5
    grid5 = current_index + [1, 0];
    if in_map(grid5, map_size)
        around_points(end+1) = points(current_index(1,1) + 1,current_index(1,2));
    end
    % 6
    grid6 = current_index + [-1, -1];
    if in_map(grid6, map_size)
        around_points(end+1) = points(current_index(1,1) - 1,current_index(1,2) - 1);
    end
    % 7
    grid7 = current_index + [0, -1];
    if in_map(grid7, map_size)
        around_points(end+1) = points(current_index(1,1),current_index(1,2) - 1);
    end
    % 8
    grid8 = current_index + [1, -1];
    if in_map(grid8, map_size)
        around_points(end+1) = points(current_index(1,1) + 1,current_index(1,2) - 1);
    end
    % x1 x2 x3
    if ~isempty(around_points)
        for i = 1:length(around_points)
            % x1
            if around_points(i).covered == 0 && ~is_obstacle(around_points(i).position, obstacles)
                around_points(i).x1 = 100;
            elseif around_points(i).covered == 1 && ~is_obstacle(around_points(i).position, obstacles)
                around_points(i).x1 = 0;
            elseif is_obstacle(around_points(i).position, obstacles)
                around_points(i).x1 = -100;
            end
            % x2
            around_points(i).x2 = -2 * sqrt((around_points(i).position(1,1) - points(current_index(1,1),current_index(1,2)).position(1,1)).^2 + ...
                                        (around_points(i).position(1,2) - points(current_index(1,1),current_index(1,2)).position(1,2)).^2);
            % x3
            around_points(i).x3 = -abs(atan2(around_points(i).position(1,1) - points(current_index(1,1),current_index(1,2)).position(1,1), ...
                                         around_points(i).position(1,2) - points(current_index(1,1),current_index(1,2)).position(1,2)));
            % check if it is in dead area
            if around_points(i).x1 == 100
                around_covered = 1;
            end
        end
        % if it is in dead area
        % use A* to escape
        if around_covered == 0
            fprintf("trap in [%d,%d], find A* path...\n",current_index(1,1)-1,current_index(1,2)-1);
            [a_star_path, current] = a_star(points(current_index(1,1), current_index(1,2)), points, obstacles);
            for i = 1:length(a_star_path)
                path(end+1) = a_star_path(i);
                points(a_star_path(i).position(1,1)+1,a_star_path(i).position(1,2)+1).covered = 1;
            end
            current_index(1,1) = current.position(1,1) + 1;
            current_index(1,2) = current.position(1,2) + 1;
        else
            max_sum = around_points(1).x1 + around_points(1).x2 + around_points(1).x3;
            max_index = 1;
            for i = 1:length(around_points)
                if around_points(i).x1 + around_points(i).x2 + around_points(i).x3 > max_sum
                    max_sum = around_points(i).x1 + around_points(i).x2 + around_points(i).x3;
                    max_index = i;
                end
            end
            current_index(1,1) = around_points(max_index).position(1,1) + 1;
            current_index(1,2) = around_points(max_index).position(1,2) + 1;
            points(current_index(1,1),current_index(1,2)).covered = 1;
            path(end+1) = points(current_index(1,1),current_index(1,2));
        end
    end
	around_points = point.empty;
	count = count + 1;
    around_covered = 0;
    if count == 2000
        fprintf("fail to cover the map completely\n");
        break;
    end
	if all_covered(points)
        fprintf("Coverage Path Planning Succeed!");
		break;
	end
end

